package com.serverclient.jdk.beanregister;

import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import com.serverclient.jdk.annotation.EnableJdkServerClient;
import com.serverclient.jdk.annotation.HttpServer;
import com.serverclient.jdk.invacation.HttpInvocationHandler;
import com.serverclient.utility.PackageScanUtility;

/**
 * 根据给定的包，扫描包下所有带有指定注解类型的class文件，并将其注册到Spring中，统一由Spring管理
 */
public class BeanRegister implements ImportBeanDefinitionRegistrar {
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		//获取指定的注解
		Map<String,Object> map = importingClassMetadata.getAnnotationAttributes(EnableJdkServerClient.class.getName());
		//获取注解中的指定项的值
		String[] packages = (String[])map.get("packages");
		Set<Class<?>> set = PackageScanUtility.getClasses(packages,HttpServer.class);
		for(Class<?> clazz : set) {
			//根据类模板创建Bean构造器
			BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
			//给构造方法添加参数，如果构造方法有多个参数，需要添加多个
			//在此功能中动态代理类Proxy.getProxyClass需要一个InvocationHandler类型的参数
			builder.addConstructorArgValue(new HttpInvocationHandler());
			AbstractBeanDefinition definition = builder.getBeanDefinition();
			//设置创建bean时使用的类模板，一般是动态代理类，getProxyClass第二个参数是生成的动态代理类应该实现的所有接口
	        definition.setBeanClass(Proxy.getProxyClass(clazz.getClassLoader(), new Class<?>[]{clazz}));
	        //注册bean
	        registry.registerBeanDefinition(clazz.getAnnotation(HttpServer.class).beanName(), definition);
		}
	}
}
